package gamebackend;

import java.util.Random;

import framework.Color;
import generators.BasicBlockGenerator;
import generators.BlockRule;
import generators.EmbiggenGenerator;
import generators.PipeGenerator;
import generators.ReplaceGenerator;
import generators.ScaredGenerator;
import generators.VerticalScaredGenerator;
import gui.BlockStyle;

public class CanyonBiome extends GameSession.Biome {
	private static final double MIN_CHANGE_LENGTH = 50;
	private static final double MAX_CHANGE_LENGTH = 120;
	
	private final Block my_wall;
	private final Block my_back;
	
	private double my_lengthBeforeChange;

	/**
	 * Whether the hard and easy path are following each other.
	 */
	private boolean my_joined;
	/**
	 * Whether the "easy" path is very narrow
	 */
	private boolean my_tiny;
	public CanyonBiome(GameSession the_session,
			int the_tier, Random the_random, double the_length) {
		the_session.super(the_session, the_tier, the_random, the_length);
		
		final Color fore;
		final Color back;
		if (the_tier == 1) {
			fore = new Color(180, 30, 70);
			back = new Color(51, 9, 20);
		} else {
			fore = new Color(70, 130, 70);
			back = new Color(20, 35, 20);
		}
		my_wall = new Block(BlockStyle.THORN, fore);
		my_back = new Block(BlockStyle.THORN, back);
		
		
		addEasyPath(new FlightPath(Block.PRIMARY_PATH, getEasyPath(), 50/*,
				new EasyFlier(getRandom(), 20, getGameSession().getWidth() - 20)*/), getLength());
		addHardPath(new FlightPath(Block.SECONDARY_PATH, getHardPath(), 16/*,
				new EasyFlier(getRandom(), 8, getGameSession().getWidth() - 8)*/), getLength());
		
		// removed as it was making too many blocks.
//		addGenerator(new BasicBlockGenerator(my_wall, BlockRule.EMPTY, getRandom(), .85), the_length);
		addGenerator(new BasicBlockGenerator(my_wall, BlockRule.EMPTY, getRandom(), .85), 200);
		
		// added to make fewer blocks than a regular basicblockgenerator
		addGenerator(new ScaredGenerator(my_wall, getRandom(), .95, .1, ScaredGenerator.BRASH), the_length);
		addGenerator(new VerticalScaredGenerator(my_wall, getRandom(), .3), the_length);
		
		addToMidGround(new PipeGenerator(Block.PRIMARY_PATH, my_back), the_length);
		addToMidGround(new EmbiggenGenerator(my_back, BlockRule.ANY), the_length);
		addToMidGround(new ReplaceGenerator(Block.SECONDARY_PATH, my_back), the_length);
	}
	public void step(final double the_yChange) {
		super.step(the_yChange);
		if (my_lengthBeforeChange < 0) {
			my_lengthBeforeChange += getRandom().nextDouble() * (MAX_CHANGE_LENGTH - MIN_CHANGE_LENGTH)
					+ MIN_CHANGE_LENGTH + 25 * getTier();
			if (my_tiny) {
				getEasyPath().setWidth(50);
				my_tiny = false;
			}
			if (my_joined) {
				System.out.println("Am joined");
				// stay together or split apart
				if (getRandom().nextDouble() < .2 + .2 * getTier()) {
					// stay together
					System.out.println("Sticking together");
					if (!my_tiny && getRandom().nextDouble() < .2 * getTier() + .2) {
						my_tiny = true;
						getEasyPath().setWidth(0);
					}
					final double ship_x = getEasyPath().getXPosition();
					final double biggest_difference = Math.max(ship_x, getWidth() - ship_x);
					double difference = (.25 + getRandom().nextDouble() * .75) * (biggest_difference - 20);
					if (my_tiny) {
						difference *= .3;
					}
					if (getRandom().nextDouble() < .5) {
						difference *= -1;
					}
					if (ship_x + difference < 20 || ship_x + difference > getWidth() - 20) {
						difference *= -1;
					}
					final double target = difference + ship_x;
					getEasyPath().getShipFlier().setTarget(target);
					getHardPath().getShipFlier().setTarget(target);
					
					// make dead start
					if (getRandom().nextDouble() < .15 * getTier()) {
						final FlightPath added = new FlightPath(Block.PRIMARY_PATH, getExtraHeight(), 30,
								new LaserShip(target + getRandom().nextDouble() * 200 - 100, 0));
						addFlightPath(added, my_lengthBeforeChange + 80);
						added.getShipFlier().setTarget(target);
					}
				} else {
					// split apart
					System.out.println("Splitting apart");
					my_lengthBeforeChange += 80;
					my_joined = false;
					// each path may go to one third of the screen.
					double[] options = new double[3];
					for (int i = 0; i < 3; i++) {
						options[i] = getRandom().nextDouble() * (getWidth() / 3 - 30) + 15;
						options[i] += i * getWidth() / 3;
					}
					// make dead start--path that starts from nowhere
					if (getRandom().nextDouble() < .5 * getTier()) {
						final int dead_start = getRandom().nextInt(3);
						final FlightPath added = new FlightPath(Block.PRIMARY_PATH, getExtraHeight(), 30,
								new LaserShip(options[dead_start] + getRandom().nextDouble() * 100 - 50, 0));
						addFlightPath(added, my_lengthBeforeChange);
						added.getShipFlier().setTarget(options[dead_start]);
					}
					// make dead end
					int dead_end = getRandom().nextInt(3);
					if (getRandom().nextDouble() < getTier() * .3 + .2) {
						final FlightPath added = new FlightPath(Block.PRIMARY_PATH, getEasyPath(), 30);
						addFlightPath(added, 200 + 100 * getTier());
						added.getShipFlier().setTarget(options[dead_end]);
					}
					if (dead_end == 0) {
						options[0] = options[2];
					} else if (dead_end == 1) {
						options[1] = options[2];
					}
					if (getRandom().nextDouble() < .5) {
						getEasyPath().getShipFlier().setTarget(options[0]);
						getHardPath().getShipFlier().setTarget(options[1]);
					} else {
						getEasyPath().getShipFlier().setTarget(options[1]);
						getHardPath().getShipFlier().setTarget(options[0]);
					}
					
				}
			} else {
				System.out.println("Am seperate");
				// stay apart or join together.
				if (getRandom().nextDouble() < .35 + .15 * getTier()) {
					// join together
					System.out.println("Joining together");
					my_joined = true;
					final double target = (getRandom().nextDouble() * (getWidth() - 40)) + 20;
					getEasyPath().getShipFlier().setTarget(target);
					getHardPath().getShipFlier().setTarget(target);
					if (getRandom().nextDouble() < getTier() * .3 + .2) {
						double dead_target = target + getRandom().nextDouble() * getWidth() - getWidth() / 2;
						final FlightPath added = new FlightPath(Block.SECONDARY_PATH, getHardPath(), 10);
						addFlightPath(added, 300 + 100 * getTier());
						added.getShipFlier().setTarget(dead_target);
					}
				} else {
					// stay apart
					System.out.println("Staying apart");
					final double between = getRandom().nextDouble() * (getWidth() - 30 - 40) + 30;
					final double left = getRandom().nextDouble() * (getWidth() - between - 40) + 20;
					System.out.println(left);
					System.out.println(left + between);
					if (getRandom().nextDouble() < .5) {
						getEasyPath().getShipFlier().setTarget(left);
						getHardPath().getShipFlier().setTarget(left + between);
					} else {
						getEasyPath().getShipFlier().setTarget(left + between);
						getHardPath().getShipFlier().setTarget(left);
					}
					
				}
			}
		}
		my_lengthBeforeChange--;
		
	}

}
